/*
 * LibraryMapImplementation.java
 *
 * Created on April 13, 2006, 10:07 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package dao.filesystem;


import dao.DaoInterface;
import domain.AbstractEntity;
import facade.ShopException;

import java.io.*;
import java.util.*;
import java.util.logging.Logger;


public abstract class AbstractFileDAO<T extends AbstractEntity> implements DaoInterface<T> {
    protected static Logger logger = Logger.getLogger(AbstractFileDAO.class.getName());

    Map<Integer, T> entitiesMap;

    protected abstract String getFileName();

    public AbstractFileDAO() throws FileNotFoundException, IOException, ClassNotFoundException, Exception {
        try {
            ObjectInputStream stream = new ObjectInputStream(new FileInputStream(getFileName()));
            entitiesMap = (Map<Integer, T>) stream.readObject();
        } catch (FileNotFoundException ex) {
            entitiesMap = new TreeMap<Integer, T>();
        }
    }


    public void save(T entity) throws Exception {
        if (entity.getId() == null) {
            SortedSet<Integer> ids = (SortedSet<Integer>) entitiesMap.keySet();
            int max = 0;
            if (!ids.isEmpty()) {
                max = ids.last();
            }
            entity.setId(max + 1);
            entitiesMap.put(entity.getId(), entity);
        } else {
            entitiesMap.put(entity.getId(), entity);

        }
    }

    public T findById(Integer id) throws Exception {
        T entity = entitiesMap.get(id);
        if (entity == null) {
            throw new ShopException("The entity does not exist");
        }
        return entity;
    }

    public Collection<T> findAll() throws Exception {
        return new ArrayList<T>(entitiesMap.values());

    }

    public void delete(Integer id) throws Exception {
        if (entitiesMap.remove(id) == null) {
            throw new ShopException("The entity does not exist");
        }
    }

    public void close() throws Exception {
        File file = new File(getFileName());

        file.createNewFile();
        ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream(getFileName()));
        stream.writeObject(entitiesMap);
        stream.close();
    }
}